#pragma once

#include<iostream>
#include<memory>
#include"Connection.hpp"
#include"Epoller.hpp"
#include"Socket.hpp"
#include"InetAddr.hpp"
#include"HandlerConnection.hpp"
#include"Log.hpp"
using namespace socket_ns;

class Listener
{
    public:
    Listener(int port ,HandlerConnection &hc)
        :_port(port)
        ,_hc(hc)
    {
        InetAddr addr("0",_port);
        _listensock->BuildListenSocket(addr);
    }
    void Acceptr(Connection *conn)
    {
        while (true)
        {
          InetAddr clientaddr;
          int code = 0;
          int sockfd = _listensock->Accepter(&clientaddr,&code);
          if(sockfd >=0)
          {
            conn->_R->AddConnection(
                sockfd,
                EPOLLIN|EPOLLET,
                std::bind(&HandlerConnection::HanlderRecv,&_hc,std::placeholders::_1),
                std::bind(&HandlerConnection::hanlderSend,&_hc,std::placeholders::_1),
                std::bind(&HandlerConnection::HanlderExcpet,&_hc,std::placeholders::_1));
          }
          else
          {
            if(code==EWOULDBLOCK||code ==EAGAIN)
            {
                LOG(DEBUG,"acceptr all link\n");
                break;
            }
            else if(code ==EINTR)
            {
                LOG(DEBUG,"accptr interuot by signal!\n");
                continue;
            }
            else
            {
                LOG(WARNING,"accept error!\n");
                break;
            }
          }
        }
    }
    int Sockfd()
    {
        return _listensock->SockFd();
    }
    ~Listener()
    {
        _listensock->Close();
    }
    private:
    uint16_t _port;
    std::unique_ptr<Socket> _listensock;
    HandlerConnection &_hc;
};